﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Text;
using Newtonsoft.Json;
using System.Collections;
using System.Data;
using System.Windows.Forms;

namespace Components
{
    public class StringUtil
    {
        private static StringUtil _instance = null;

        public static StringUtil Entity
        {
            get
            {
                if (_instance == null)
                    return new StringUtil();
                return _instance;
            }
        }

        /// <summary>
        /// 将对象转换成JSON字符串
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public string DeserializeObject(object o)
        {
            return (o == null) ? "{}" : JavaScriptConvert.SerializeObject(o);
        }

        /// <summary>
        /// 将多个HashTable合并成一个Json字符串
        /// </summary>
        /// <param name="overrideKey">如果后面的Hashtable中有和前面的Table中一样的键，是否覆盖</param>
        /// <param name="hts"></param>
        /// <returns></returns>
        public string MergeToJson(bool overrideKey, params Hashtable[] hts)
        {
            if (hts == null || 0 == hts.Length) return "{}";

            Hashtable lastTable = new Hashtable();
            foreach (Hashtable ht in hts)
            {
                if (null == ht) continue;
                foreach (DictionaryEntry entry in ht)
                {
                    if (!overrideKey && lastTable.ContainsKey(entry.Key.ToString())) continue; // 不覆盖

                    lastTable[entry.Key.ToString()] = entry.Value;
                }
            }

            return TableToJson(lastTable); //将值转换成JSON
        }

        /// <summary>
        /// Hash转换成Json ===========暂时写简单点，具体需求具体分析
        /// </summary>
        /// <param name="ht"></param>
        /// <returns></returns>
        public string TableToJson(Hashtable ht)
        {
            if (ht == null || ht.Count == 0) return "{}";
            StringBuilder sb = new StringBuilder();

            foreach (DictionaryEntry entry in ht)
            {
                if (sb.Length != 0) sb.Append(",");
                sb.AppendFormat("\"{0}\":\"{1}\"", SaveString(entry.Key), SaveString(entry.Value));
            }

            return string.Format("{{{0}}}", sb.ToString());
        }

        public string KvToJSON(KeyValuePair<string, object>[] ht)
        {
            if (ht == null || ht.Length == 0) return "{}";
            StringBuilder sb = new StringBuilder();

            foreach (KeyValuePair<string, object> s in ht)
            {
                if (sb.Length != 0) sb.Append(",");
                sb.AppendFormat("\"{0}\":\"{1}\"", SaveString(s.Key), SaveString(s.Value));
            }

            return string.Format("{{{0}}}", sb.ToString());
        }


        public string SaveString(object o)
        {
            if (o == null) return "";

            return o.ToString().Replace("\\", "\\\\").Replace("\"", "'");
        }

        /// <summary>
        /// JSON 转 Hashtable 
        /// </summary>
        /// <param name="json">json 字符串</param>
        /// <param name="ignoreCase">Hashtable中的键是否大写</param>
        /// <returns></returns>
        public Hashtable JsonToTable(string json, bool ignoreCase)
        {
            Hashtable hs = new Hashtable();
            try
            {
                JavaScriptObject jsArray = JavaScriptConvert.DeserializeObject(json) as JavaScriptObject;
                object pValue = "";
                string key = "";
                if (jsArray != null)
                {
                    foreach (KeyValuePair<string, object> kvp in jsArray)
                    {
                        pValue = (null == kvp.Value) ? "" : kvp.Value;
                        key = (ignoreCase == true) ? kvp.Key.ToLower() : kvp.Key;
                        hs[key] = pValue;
                    }
                }
            }
            catch
            {
                return hs;
            }

            return hs;

        }

        /// <summary>
        /// DataTable 转换成JSON
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public string DataTableToJSON(DataTable dt)
        {
            StringBuilder JsonString = new StringBuilder();
            if (dt != null && dt.Rows.Count > 0)
            {
                JsonString.Append("{ ");
                JsonString.Append("\"data\":[ ");
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    JsonString.Append("{ ");
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        if (j < dt.Columns.Count - 1)
                        {
                            JsonString.Append("\"" + SaveString(dt.Columns[j].ColumnName) + "\":" + "\"" + SaveString(dt.Rows[i][j]) + "\",");
                        }
                        else if (j == dt.Columns.Count - 1)
                        {
                            JsonString.Append("\"" + SaveString(dt.Columns[j].ColumnName) + "\":" + "\"" + SaveString(dt.Rows[i][j]) + "\"");
                        }
                    }
                    /**/
                    /*end Of String*/
                    if (i == dt.Rows.Count - 1)
                    {
                        JsonString.Append("} ");
                    }
                    else
                    {
                        JsonString.Append("}, ");
                    }
                }
                JsonString.Append("]}");
                return JsonString.ToString();
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// GridView 转换成JSON数组
        /// </summary>
        /// <param name="grid"></param>
        /// <returns></returns>
        public string DataGridViewToJSON(DataGridView grid)
        {
            if (null == grid || 0 == grid.Rows.Count) return "{}";

            StringBuilder JsonString = new StringBuilder();
            JsonString.Append("{ ");
            JsonString.Append("\"data\":[ ");
            for (int i = 0; i < grid.Rows.Count; i++)
            {
                JsonString.Append("{ ");
                for (int j = 0; j < grid.Columns.Count; j++)
                {
                    if (j < grid.Columns.Count - 1)
                    {
                        JsonString.Append("\"" + SaveString(grid.Columns[j].Name) + "\":" + "\"" + SaveString(grid.Rows[i].Cells[j].Value) + "\",");
                    }
                    else if (j == grid.Columns.Count - 1)
                    {
                        JsonString.Append("\"" + SaveString(grid.Columns[j].Name) + "\":" + "\"" + SaveString(grid.Rows[i].Cells[j].Value) + "\"");
                    }
                }

                /*end Of String*/
                if (i == grid.Rows.Count - 1)
                {
                    JsonString.Append("} ");
                }
                else
                {
                    JsonString.Append("}, ");
                }
            }
            JsonString.Append("]}");
            return JsonString.ToString();
        }

        /// <summary>
        /// 判断某个字符数组中是否有存在的字符
        /// </summary>
        /// <param name="key">目标字符</param>
        /// <param name="strArray">字符数组</param>
        /// <param name="ignoreCase">是否忽略大小写</param>
        /// <returns></returns>
        public bool InArray(string key, bool ignoreCase, params string[] strArray)
        {
            if (strArray == null)
            {
                return false;
            }

            foreach (string sourceWord in strArray)
            {
                if (ignoreCase) // 忽略大小写
                {
                    if (sourceWord.ToUpper() == key.ToUpper())
                    {
                        return true;
                    }
                }
                else
                {
                    if (sourceWord == key)
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        public static string Zip(string str)
        {
            return Convert.ToBase64String(Compress(Convert.FromBase64String(Convert.ToBase64String(Encoding.Default.GetBytes(str)))));
        }

        public static string UnZip(string str)
        {
            return Encoding.Default.GetString(Decompress(Convert.FromBase64String(str)));
        }

        public static byte[] Compress(byte[] data)
        {
            MemoryStream ms = new MemoryStream();
            GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true);
            zip.Write(data, 0, data.Length);
            zip.Close();
            byte[] buffer = new byte[ms.Length];
            ms.Position = 0;
            ms.Read(buffer, 0, buffer.Length);
            ms.Close();
            return buffer;
        }
        public static byte[] Decompress(byte[] data)
        {
            MemoryStream ms = new MemoryStream(data);
            GZipStream zip = new GZipStream(ms, CompressionMode.Decompress, true);
            MemoryStream msreader = new MemoryStream();
            byte[] buffer = new byte[0x1000];
            while (true)
            {
                int reader = zip.Read(buffer, 0, buffer.Length);
                if (reader <= 0)
                {
                    break;
                }
                msreader.Write(buffer, 0, reader);
            }
            zip.Close();
            ms.Close();
            msreader.Position = 0;
            buffer = msreader.ToArray();
            msreader.Close();
            return buffer;
        }

    }
}
